{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 线性回归的示例\n",
    "\n",
    "TensorFlow v2库的线性回归实现"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from __future__ import absolute_import, division, print_function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "import numpy as np\n",
    "rng = np.random"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义参数\n",
    "learning_rate = 0.01\n",
    "training_steps = 1000\n",
    "display_step = 50"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 训练数据\n",
    "X = np.array([3.3,4.4,5.5,6.71,6.93,4.168,9.779,6.182,7.59,2.167,\n",
    "              7.042,10.791,5.313,7.997,5.654,9.27,3.1])\n",
    "Y = np.array([1.7,2.76,2.09,3.19,1.694,1.573,3.366,2.596,2.53,1.221,\n",
    "              2.827,3.465,1.65,2.904,2.42,2.94,1.3])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 权重（weight）和偏差（bias），随机初始化\n",
    "W = tf.Variable(rng.randn(), name=\"weight\")\n",
    "b = tf.Variable(rng.randn(), name=\"bias\")\n",
    "\n",
    "# 线性回归(Wx + b).\n",
    "def linear_regression(x):\n",
    "    return W * x + b\n",
    "\n",
    "\n",
    "def mean_square(y_pred, y_true):\n",
    "    return tf.reduce_mean(tf.square(y_pred - y_true))  # tf.square()是张量对里面的每一个元素求平方\n",
    "\n",
    "# 随机梯度下降优化\n",
    "optimizer = tf.optimizers.SGD(learning_rate)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 优化过程 \n",
    "def run_optimization():\n",
    "    # 在GradientTape内计算，以实现自动微分\n",
    "    with tf.GradientTape() as g:\n",
    "        pred = linear_regression(X)\n",
    "        loss = mean_square(pred, Y)\n",
    "\n",
    "    # 计算梯度\n",
    "    gradients = g.gradient(loss, [W, b])\n",
    "    \n",
    "    # 根据梯度更新W和b\n",
    "    optimizer.apply_gradients(zip(gradients, [W, b]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "step: 50, loss: 0.153872, W: 0.253145, b: 0.788095\n",
      "step: 100, loss: 0.153869, W: 0.252972, b: 0.789320\n",
      "step: 150, loss: 0.153866, W: 0.252819, b: 0.790405\n",
      "step: 200, loss: 0.153865, W: 0.252684, b: 0.791366\n",
      "step: 250, loss: 0.153863, W: 0.252564, b: 0.792217\n",
      "step: 300, loss: 0.153862, W: 0.252457, b: 0.792970\n",
      "step: 350, loss: 0.153861, W: 0.252363, b: 0.793638\n",
      "step: 400, loss: 0.153860, W: 0.252280, b: 0.794228\n",
      "step: 450, loss: 0.153860, W: 0.252206, b: 0.794752\n",
      "step: 500, loss: 0.153859, W: 0.252141, b: 0.795215\n",
      "step: 550, loss: 0.153859, W: 0.252083, b: 0.795626\n",
      "step: 600, loss: 0.153859, W: 0.252032, b: 0.795989\n",
      "step: 650, loss: 0.153858, W: 0.251986, b: 0.796311\n",
      "step: 700, loss: 0.153858, W: 0.251946, b: 0.796596\n",
      "step: 750, loss: 0.153858, W: 0.251910, b: 0.796848\n",
      "step: 800, loss: 0.153858, W: 0.251879, b: 0.797072\n",
      "step: 850, loss: 0.153858, W: 0.251851, b: 0.797270\n",
      "step: 900, loss: 0.153858, W: 0.251826, b: 0.797445\n",
      "step: 950, loss: 0.153858, W: 0.251804, b: 0.797600\n",
      "step: 1000, loss: 0.153858, W: 0.251785, b: 0.797737\n"
     ]
    }
   ],
   "source": [
    "# 按照给定的步骤数进行训练\n",
    "for step in range(1, training_steps + 1):\n",
    "    # 运行优化以更新W和b值\n",
    "    run_optimization()\n",
    "    \n",
    "    if step % display_step == 0:\n",
    "        pred = linear_regression(X)\n",
    "        loss = mean_square(pred, Y)\n",
    "        print(\"step: %i, loss: %f, W: %f, b: %f\" % (step, loss, W.numpy(), b.numpy()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 图形展示\n",
    "plt.plot(X, Y, 'ro', label='Original data')\n",
    "plt.plot(X, np.array(W * X + b), label='Fitted line')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
